//----------------------------------------------------------------------------------------------
//	Filename:	PointCloudScene.h
//	Author:		Sandro Spina
//	Date:		03/08/2012
//----------------------------------------------------------------------------------------------
#pragma once

#include <iostream>
#include <fstream>
#include <map>

#include <boost/filesystem.hpp>
#include <boost/shared_ptr.hpp>

#include "System/IlluminaPRT.h"
#include "System/EngineKernel.h"
#include "Scene/SceneLoader.h"
#include "Shape/VertexFormats.h"

class PointCloudContext;

//----------------------------------------------------------------------------------------------
namespace Illumina
{
	namespace Core
	{
		//----------------------------------------------------------------------------------------------
		class PointCloudSceneLoader
			: public ISceneLoader
		{
		protected:
			using ISceneLoader::m_pEnvironment;

		protected:
			EngineKernel* m_pEngineKernel;

		public:
			PointCloudSceneLoader(Environment *p_pEnvironment);

			bool Import(const std::string &p_strFilename, unsigned int p_uiFlags, ArgumentMap* p_pArgumentMap = NULL);
			bool Export(const std::string &p_strFilename, unsigned int p_uiFlags, ArgumentMap* p_pArgumentMap = NULL);			
		
		protected:			
			bool LoadOBJGeometry(const std::string &p_strFilename, PointCloudContext &p_context, float p_min_dist, float p_max_dist, 
								float p_radius, float p_scale, float p_curvature, float p_cornerRatioEpsilon, int p_kNNType, int p_kNNFlood, 
								float p_kNNTypeRadius, float p_kNNFloodRadius, int p_kNNTypeMode, int p_kNNFloodMode, int p_edgeCornerDetect, float p_noise);
			
			bool LoadOBJGeometry(const std::string &p_strFilename, PointCloudContext &p_context, float p_min_dist, float p_max_dist, 
								float p_radius, float p_scale, float p_curvature, float p_cornerRatioEpsilon, int p_kNNType, int p_kNNFlood, 
								float p_kNNTypeRadius, float p_kNNFloodRadius, int p_kNNTypeMode, int p_kNNFloodMode, int p_edgeCornerDetect, float p_noise, int p_scans);

			bool LoadBLABPoints(const std::string &p_strFilename, PointCloudContext &p_context, float p_min_dist, float p_max_dist, 
								float p_radius, float p_scale, float p_curvature, float p_cornerRatioEpsilon, int p_kNNType, int p_kNNFlood, 
								float p_kNNTypeRadius, float p_kNNFloodRadius, int p_kNNTypeMode, int p_kNNFloodMode, int p_edgeCornerDetect, float p_noise, float p_coplanarDst);

			bool LoadPCSGeometry(const std::string &p_strFilename, PointCloudContext &p_context, float p_min_dist, float p_max_dist,
								float p_radius, float p_scale, float p_curvature, float p_cornerRatioEpsilon, int p_kNNType, int p_kNNFlood, 
								float p_kNNTypeRadius, float p_kNNFloodRadius, int p_kNNTypeMode, int p_kNNFloodMode, int p_edgeCornerDetect, float p_noise, float p_coplanarDst);

			bool LoadASCGeometry(const std::string &p_strFilename, PointCloudContext &p_context, float p_min_dist, float p_max_dist,
								float p_radius, float p_scale, float p_curvature, float p_cornerRatioEpsilon, int p_kNNType, int p_kNNFlood, 
								float p_kNNTypeRadius, float p_kNNFloodRadius, int p_kNNTypeMode, int p_kNNFloodMode, int p_edgeCornerDetect, float p_noise, float p_coplanarDst);

			bool GenerateLWPCGeometry(PointCloudContext &p_context, float p_density, float p_radius, float p_scale, int p_surfaces, int p_kNNType, 
										int p_kNNFlood, float p_kNNTypeRadius, float p_kNNFloodRadius);

			bool GeneratePWPCGeometry(PointCloudContext &p_context, float p_min_dist, float p_max_dist, float p_radius, float p_scale, int p_surfaces, 
										float p_curvature, float p_cornerRatioEpsilon, int p_kNNType, int p_kNNFlood, float p_kNNTypeRadius, 
										float p_kNNFloodRadius, int p_kNNTypeMode, int p_kNNFloodMode, int p_edgeCornerDetect, float p_noise);

			//std::map<std::string, std::string> ImportModelsForTraining(std::string p_strFilename);
		}; 
		//----------------------------------------------------------------------------------------------
	}
}
